#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <math.h>
#include <limits.h>
#include <time.h>
#include "main.h"

struct packet *N, *M, *Y, *Z;

void initializePacketArrayForEachService() {
    M = (struct packet*) malloc(MAX_NUM_MEGAVIDEO_USER_PACKETS*sizeof(struct packet));
    if (M == NULL)
        printf("DONE");
    Y = (struct packet*) malloc(MAX_NUM_YOUTUBE_USER_PACKETS*sizeof(struct packet));
    Z = (struct packet*) malloc(MAX_NUM_ZSHARE_USER_PACKETS*sizeof(struct packet));
    N = (struct packet*) malloc(MAX_NUM_NETFLIX_USER_PACKETS*sizeof(struct packet));
    
}

void initializeEverythingElseForAllServices() {
    int packetCounter = 0;
    Time tv;
	struct packet* temp;
	
    int UserCounter = 0, dslamCounter = 0, brasCounter = 0;
    for (packetCounter = 0; packetCounter < MAX_NUM_MEGAVIDEO_USER_PACKETS; packetCounter++) {
        temp = M + packetCounter;
        temp->source = 'M';
        temp->userNumber = UserCounter;
        temp->dslamNumber = dslamCounter;
        temp->brasNumber = brasCounter;
       
        UserCounter++;
        if(UserCounter == NUM_USER) {
           dslamCounter++;
           UserCounter=0;
        }
        if(dslamCounter == NUM_DSLAM) {
           brasCounter++;
           dslamCounter=0;
        }
        if(brasCounter == NUM_BRAS) {
           brasCounter=0;
        }

        gettimeofday(&tv, NULL);
        temp->internetDispatchTime = tv;
    }
    
    UserCounter = 0; dslamCounter = 0; brasCounter = 0;
    for (packetCounter = 0; packetCounter < MAX_NUM_NETFLIX_USER_PACKETS; packetCounter++) {
        temp = N + packetCounter;
        temp->source = 'N';
        temp->userNumber = UserCounter;
        temp->dslamNumber = dslamCounter;
        temp->brasNumber = brasCounter;
       
        UserCounter++;
        if(UserCounter == NUM_USER) {
           dslamCounter++;
           UserCounter=0;
        }
        if(dslamCounter == NUM_DSLAM) {
           brasCounter++;
           dslamCounter=0;
        }
        if(brasCounter == NUM_BRAS) {
           brasCounter=0;
        }

        gettimeofday(&tv, NULL);
        temp->internetDispatchTime = tv;
    }
    
    UserCounter = 0; dslamCounter = 0; brasCounter = 0;
    for (packetCounter = 0; packetCounter < MAX_NUM_YOUTUBE_USER_PACKETS; packetCounter++) {
        temp = Y + packetCounter;
        temp->source = 'Y';
        temp->userNumber = UserCounter;
        temp->dslamNumber = dslamCounter;
        temp->brasNumber = brasCounter;
       
        UserCounter++;
        if(UserCounter == NUM_USER) {
           dslamCounter++;
           UserCounter=0;
        }
        if(dslamCounter == NUM_DSLAM) {
           brasCounter++;
           dslamCounter=0;
        }
        if(brasCounter == NUM_BRAS) {
           brasCounter=0;
        }

        gettimeofday(&tv, NULL);
        temp->internetDispatchTime = tv;
    }
    
    UserCounter = 0; dslamCounter = 0; brasCounter = 0;
    for (packetCounter = 0; packetCounter < MAX_NUM_ZSHARE_USER_PACKETS; packetCounter++) {
        temp = Z + packetCounter;
        temp->source = 'Z';
        temp->userNumber = UserCounter;
        temp->dslamNumber = dslamCounter;
        temp->brasNumber = brasCounter;
       
        UserCounter++;
        if(UserCounter == NUM_USER) {
           dslamCounter++;
           UserCounter=0;
        }
        if(dslamCounter == NUM_DSLAM) {
           brasCounter++;
           dslamCounter=0;
        }
        if(brasCounter == NUM_BRAS) {
           brasCounter=0;
        }

        gettimeofday(&tv, NULL);
        temp->internetDispatchTime = tv;
    }
}

void printServiceLists() {
    int packetCounter = 0;
	struct packet *temp;
	FILE * pFile;

	pFile = fopen ("Megavideo.txt","w");
    fprintf(pFile, "User list for Megavideo: \n");
    for (packetCounter = 0; packetCounter < MAX_NUM_MEGAVIDEO_USER_PACKETS; packetCounter++) {
        temp = M + packetCounter;
        fprintf(pFile, "dispatchTime(s): %d\t\t dispatchTime(us): %d\t\t source: %c\t BRAS: %d\t DSLAM: %d\t User: %d\n", 
        				temp->internetDispatchTime.tv_sec, temp->internetDispatchTime.tv_usec, temp->source, temp->brasNumber, temp->dslamNumber, temp->userNumber);
    }
    fclose (pFile);

    pFile = fopen ("Netflix.txt","w");
    fprintf(pFile, "User list for Netflix: \n");
    for (packetCounter = 0; packetCounter < MAX_NUM_NETFLIX_USER_PACKETS; packetCounter++) {
        temp = N + packetCounter;
        fprintf(pFile, "dispatchTime(s): %d\t\t dispatchTime(us): %d\t\t source: %c\t BRAS: %d\t DSLAM: %d\t User: %d\n", 
        				temp->internetDispatchTime.tv_sec, temp->internetDispatchTime.tv_usec, temp->source, temp->brasNumber, temp->dslamNumber, temp->userNumber);
    }
    fclose (pFile);

	pFile = fopen ("YouTube.txt","w");
    fprintf(pFile, "User list for YouTube: \n");
    for (packetCounter = 0; packetCounter < MAX_NUM_YOUTUBE_USER_PACKETS; packetCounter++) {
        temp = Y + packetCounter;
        fprintf(pFile, "dispatchTime(s): %d\t\t dispatchTime(us): %d\t\t source: %c\t BRAS: %d\t DSLAM: %d\t User: %d\n", 
        				temp->internetDispatchTime.tv_sec, temp->internetDispatchTime.tv_usec, temp->source, temp->brasNumber, temp->dslamNumber, temp->userNumber);
    }
    fclose (pFile);
    
    pFile = fopen ("Zshare.txt","w");
    fprintf(pFile, "User list for Zshare: \n");
    for (packetCounter = 0; packetCounter < MAX_NUM_ZSHARE_USER_PACKETS; packetCounter++) {
        temp = Z + packetCounter;
        fprintf(pFile, "dispatchTime(s): %d\t\t dispatchTime(us): %d\t\t source: %c\t BRAS: %d\t DSLAM: %d\t User: %d\n", 
        				temp->internetDispatchTime.tv_sec, temp->internetDispatchTime.tv_usec, temp->source, temp->brasNumber, temp->dslamNumber, temp->userNumber);
    }
    fclose (pFile);
}

void printMuxedArray(struct packet *muxedPacketArray, int totalNumberOfPackets)
{
	int packetCounter = 0;
	struct packet *temp;
	FILE * pFile;
	pFile = fopen ("ALL.txt","w");
	
	for (packetCounter = 0; packetCounter < totalNumberOfPackets; packetCounter++) 
	{
        temp = muxedPacketArray + packetCounter;
        fprintf(pFile, "dispatchTime(s): %d\t\t dispatchTime(us): %d\t\t source: %c\t\t BRAS: %d\t DSLAM: %d\t User: %d\n", 
        				temp->internetDispatchTime.tv_sec, temp->internetDispatchTime.tv_usec, temp->source, temp->brasNumber, temp->dslamNumber, temp->userNumber);
    }
    fclose (pFile);
}

int main() {
    initializePacketArrayForEachService();
    initializeEverythingElseForAllServices();
    printServiceLists();
    
    int num_muxed_packet_array = MAX_NUM_MEGAVIDEO_USER_PACKETS + MAX_NUM_NETFLIX_USER_PACKETS + MAX_NUM_YOUTUBE_USER_PACKETS + MAX_NUM_ZSHARE_USER_PACKETS;
    struct packet *muxedPacketArray;
    muxedPacketArray = (struct packet*) malloc(num_muxed_packet_array*sizeof(struct packet));
    int totalNumberOfPackets = mux(M, N, Y, Z, muxedPacketArray);
    
    printMuxedArray(muxedPacketArray, totalNumberOfPackets);
	
    return 0;
}

